function Commons()
{
	var filters = new Filters();
	/*PictureUploader begins*/
	function PictureUploader(previewer, triggerButton)
	{
		this.theForm = $("<form method=\"post\" enctype=\"multipart/form-data\" style=\"display: none;\"></form>");
		this.init = function()
		{
			var thisObj = this;
			triggerButton.on("click", function(){
				thisObj.loadImage();
			});
		};
		
		this.loadImage = function()
		{
			this.theForm.empty();
			var i =  $("<input name=\"imageUrl\" type=\"file\" accept=\"image/*\" />");
			this.theForm.append(i);
			var thisObj = this;
			var onLoadImage = function()
			{
				var input = this;
				if (input.files && input.files[0]) {
					var reader = new FileReader();
					reader.onload = function (e) {
						
						previewer.empty();
						var img = $("<img></img>");
						img.attr('src', e.target.result);
						previewer.append(img);
					};
					reader.readAsDataURL(input.files[0]);
				}
			};
			$(i).on("change", onLoadImage);
			$(i).trigger("click");
		};
		this.init();
	};
	this.runFilters = function(onSuccessFx)
	{
		var result = filters.execute();
		if(result.error)
		{
			result.displayErrors();
			return;
		}
		else
		{
			onSuccessFx();
		}
	}
	this.appendFilter = function(obj)
	{
		filters.appendFilter(obj);
	};
	this.filters = function()
	{
		return filters.filterTypes;
	}
	this.goTo = function(url)
	{
		window.location.href = url;
	};
	this.refresh = function()
	{
		window.location.reload();
	};
	this.handleResponseError = function(response)
	{
		if(response.error)
		{
			alert(response.message);
		}
		return response.error;
	};
	this.getPictureUploader = function(previewer, triggerButton)
	{
		return new PictureUploader(previewer, triggerButton);
	};

	this.addUrlParam = function(url, param, value)
	{
		value.replace("?", "");
		if(!url.endsWith("?") && url.indexOf("?") == -1)
		{
			url += "?";
		}
		if(url.split("?")[1] !== "")
		{
			url += "&";
		}
		return url += param + "=" + value;
	};

	this.isEmptyObject = function(obj) {
	  return Object.getOwnPropertyNames(obj).length === 0;
	}
}
if(typeof String.prototype.endsWith !== 'function') {
    String.prototype.endsWith = function(suffix) {
        return this.indexOf(suffix, this.length - suffix.length) !== -1;
    };
}

/*Filters begins*/
function Filters()
{
	var thisObj = this;
	this.NUMBERS_ONLY = 1;
	this.NAME = 2;
	this.EMAIL = 3;
	this.MIN_SIZE = 4;
	this.MAX_SIZE = 5;
	this.MATCH_PATTERN = 6;
	this.NOT_EMPTY = 7;
	this.IS_ADULT = 8;
	this.LETTERS_ONLY = 10;
	this.DECIMAL = 11;
	this.GREATER_THAN = 12;
	this.LESS_THAN = 13;
	this.PASSWORD_MATCH = 14;

	this.filterTypes = 
	{
		NUMBERS_ONLY: this.NUMBERS_ONLY,
		NAME: this.NAME,
		EMAIL: this.EMAIL,
		MIN_SIZE: this.MIN_SIZE,
		MAX_SIZE: this.MAX_SIZE,
		MATCH_PATTERN: this.MATCH_PATTERN,
		IS_ADULT: this.IS_ADULT,
		LETTERS_ONLY: this.LETTERS_ONLY,
		DECIMAL: this.DECIMAL,
		GREATER_THAN: this.GREATER_THAN,
		LESS_THAN: this.LESS_THAN,
		PASSWORD_MATCH: this.PASSWORD_MATCH
	}

	this.filters = {};

	this.filters[this.NUMBERS_ONLY] = {
		validateFx: function(val, fieldName, message){
			message = message || "El campo "+fieldName+" sólo puede tener valores numéricos en el rango de 0 - 9";
			var error = false;
			if(!val.match(/^[0-9]+$/))
			{
				error = message;
			}
			return error;
		}
	};

	this.filters[this.NAME] = {
		validateFx: function(val, fieldName, message){
			message = message || "El campo "+fieldName+" sólo puede tener letras de la a-z mayúsculas o minúsculas, y sólo un espacio entre nombres.";
			var error = false;
			if(!val.match(/^[a-zA-Z]+(\s[a-zA-Z]+){0,2}$/))
			{
				error = message;
			}
			return error;
		}
	};

	this.filters[this.LETTERS_ONLY] = {
		validateFx: function(val, fieldName, message){
			message = message || "El campo "+fieldName+" sólo puede tener letras de la a-z mayúsculas o minúsculas.";
			var error = false;
			if(!val.match(/^[a-zA-Z]+$/))
			{
				error = message;
			}
			return error;
		}
	};

	this.filters[this.EMAIL] = {
		validateFx: function(val, fieldName, message){
			message = message || "El campo "+fieldName+" debe ser un email válido.";
			var error = false;
			if(!val.match(/^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/))
			{
				error = message || this.message;
			}
			return error;
		}
	};

	this.filters[this.MIN_SIZE] = {
		validateFx: function(val, fieldName, message, extraval){
			message = message || "El campo "+fieldName+" debe tener al menos "+extraval+" caracteres.";
			var error = false;
			if(val.length < extraval)
			{
				error = message || this.message;
			}
			return error;
		}
	};

	this.filters[this.MAX_SIZE] = {
		validateFx: function(val, fieldName, message, extraval){
			message = message || "El campo "+fieldName+" debe tener no más de "+extraval+" caracteres.";
			var error = false;
			if(val.length > extraval)
			{
				error = message || this.message;
			}
			return error;
		}
	};

	this.filters[this.MATCH_PATTERN] = {
		validateFx: function(val, fieldName, message, extraval){
			var error = false;
			if(!val.match(extraval))
			{
				error = message;
			}
			return error;
		}
	};

	this.filters[this.NOT_EMPTY] = {
		validateFx: function(val, fieldName, message){
			message = message || "El campo "+fieldName+" no puede estar vacío.";
			var error = false;
			if(!val || val.length == 0)
			{
				error = message || this.message;
			}
			return error;
		}
	};

	this.filters[this.IS_ADULT] = {
		validateFx: function(val, fieldName, message){
			var birthDate = new Date(Date.parse(val));
			var error = false;
			var tempDate = new Date(birthDate.getFullYear() + 18, birthDate.getMonth(), birthDate.getDate());
			message = message || "La persona debe ser mayor a 18 años.";
			if(tempDate > new Date())
			{
				error = message || this.message;
			}
			return error;
		}
	};

	this.filters[this.DECIMAL] = {
		validateFx: function(val, fieldName, message){
			var error = false;
			val +="";
			if(!val.match(/^[0-9]*\.?[0-9]+$/))
			{
				error = message || "El campo "+fieldName+" debe ser una cantidad entera o decimal no negativa.";
			}
			return error;
		}
	};

	this.filters[this.LESS_THAN] = {
		validateFx: function(val, fieldName, message, extraval){
			extraval = extraval || 0;
			var error = false;
			val = parseFloat(val);
			extraval = parseFloat(extraval);
			if((!val && val != 0) || (!extraval && extraval != 0))
			{
				return "";
			}
			if(val > extraval)
			{
				error = message || "El campo "+fieldName+" no puede ser mayor a "+extraval;
			}
			return error;
		}
	};

	this.filters[this.GREATER_THAN] = {
		validateFx: function(val, fieldName, message, extraval){
			extraval = extraval || 0;
			var error = false;
			val = parseFloat(val);
			extraval = parseFloat(extraval);
			if((!val && val != 0) || (!extraval && extraval != 0))
			{
				return "";
			}
			if(val <= extraval)
			{
				error = message || "El campo "+fieldName+" no puede ser menor a "+extraval;
			}
			return error;
		}
	};

	this.filters[this.PASSWORD_MATCH] = {
		validateFx: function(val, fieldName, message, extraval){
			extraval = extraval || "";
			var error = false;
			if(val !== extraval)
			{
				error = message || "Las contraseñas no coinciden.";
			}
			return error;
		}
	};
	

	var elementsToFilter = [];
	this.appendFilter = function(obj)
	{
		elementsToFilter.push(obj);	
	};

	this.execute = function()
	{
		var response = {
			messages: [],
			error: false,
			displayErrors: function()
			{
				alert(this.messages.join("\n").replace(/^(\\n)+$/, "\n"));
			}
		};
		var executeValidation = function(element, filter)
		{
			var res = thisObj.filters[filter].validateFx(
					(element.val && typeof element.val === "string" ? element.val.trim() : element.val),
					element.name,
					element.message,
					element.extraval
					);
			return res;
		}
		for(var i = 0; i<elementsToFilter.length; i++)
		{
			var element = elementsToFilter[i];
			var error = executeValidation(element, thisObj.NOT_EMPTY);
			if(error && element.canBeEmpty)
			{
				continue;
			}
			else if(error)
			{
				if(response.messages.indexOf(error) == -1)
				{
					response.messages.push(error);
				}
				
				continue;
			}
			if(element.filters instanceof Array)
			{
				for(var j=0; j<element.filters.length; j++)
				{
					error = executeValidation(element, element.filters[j]);
					if(error)
					{
						response.messages.push(error);
					}
				}
			}
			else
			{
				error = executeValidation(element, element.filters);
				if(error)
				{
					response.messages.push(error);
				}
			}
		}

		if(response.messages.length > 0)
		{
			response.error = true;
		}
		elementsToFilter = [];
		return response;
	}
};

var util = new Commons();

$body = $("body");

$(document).on({
    ajaxStart: function() { $body.addClass("loading");    },
     ajaxStop: function() { $body.removeClass("loading"); }    
});